/* QtLua -- Lua bindings for Qt
   Copyright (C) 2011, Jarek Pelczar

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General
   Public License along with this library; if not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301 USA

*/

#include "qluascriptbreakpointmodel_p.h"
#include "qluabreakpointdata_p.h"

class QLuaScriptBreakpointModelPrivate
{
public:
    QLuaScriptBreakpointModelPrivate();
    ~QLuaScriptBreakpointModelPrivate();

    QList<QLuaBreakpointData> m_data;
};

QLuaScriptBreakpointModelPrivate::QLuaScriptBreakpointModelPrivate()
{
}

QLuaScriptBreakpointModelPrivate::~QLuaScriptBreakpointModelPrivate()
{
}

QLuaScriptBreakpointModel::QLuaScriptBreakpointModel(QObject *parent) :
    QAbstractItemModel(parent)
{
    d = new QLuaScriptBreakpointModelPrivate();
}

QLuaScriptBreakpointModel::~QLuaScriptBreakpointModel()
{
    delete d;
}

QModelIndex QLuaScriptBreakpointModel::index(int row, int column,
                          const QModelIndex &parent) const
{
    if(parent.isValid())
        return QModelIndex();
    if(row < 0 || row >= d->m_data.count())
        return QModelIndex();
    if(column < 0 || column >= columnCount())
        return QModelIndex();
    return createIndex(row, column);
}

QModelIndex QLuaScriptBreakpointModel::parent(const QModelIndex &child) const
{
    return QModelIndex();
}

int QLuaScriptBreakpointModel::rowCount(const QModelIndex &parent) const
{
    if(parent.isValid())
        return 0;
    return d->m_data.count();
}

int QLuaScriptBreakpointModel::columnCount(const QModelIndex &parent) const
{
    if(parent.isValid())
        return 0;
    return 5;
}

QVariant QLuaScriptBreakpointModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid() || index.row() >= d->m_data.count())
        return QVariant();
    const QLuaBreakpointData& item = d->m_data.at(index.row());
    if(role == Qt::DisplayRole)
    {
        switch(index.column())
        {
        case 0: return item.id();
        case 1: {
                QString loc = item.fileName();
                loc.append(QString::fromLatin1(":%1").arg(item.lineNumber()));
                return loc;
            }
            break;
        case 2: return item.ignoreCount();
        case 3: return item.isSingleShot();
        case 4: return item.hitCount();
        }
    } else if(role == Qt::CheckStateRole) {
        if(index.column() == 0)
            return item.isEnabled() ? Qt::Checked : Qt::Unchecked;
        if(index.column() == 3)
            return item.isSingleShot() ? Qt::Checked : Qt::Unchecked;
    } else if(role == Qt::EditRole) {
        if(index.column() == 2)
            return item.ignoreCount();
    }
    return QVariant();
}

bool QLuaScriptBreakpointModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid() || index.row() >= d->m_data.count())
        return false;
    const QLuaBreakpointData& item = d->m_data.at(index.row());
    QLuaBreakpointData modified;

    if(index.column() == 0) {
        if(role == Qt::CheckStateRole) {
            modified = item;
            modified.setEnabled(value.toInt() == Qt::Checked);
        }
    } else if(index.column() == 2) {
        if(role == Qt::EditRole) {
            modified = item;
            modified.setIgnoreCount(value.toInt());
        }
    } else if(index.column() == 3) {
        if(role == Qt::CheckStateRole) {
            modified = item;
            modified.setSingleShot(value.toInt() == Qt::Checked);
        }
    }

    if(!modified.isValid())
        return false;

    d->m_data[index.row()] = modified;

    return true;
}

QVariant QLuaScriptBreakpointModel::headerData(int section, Qt::Orientation orientation,
                            int role) const
{
    if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        switch(section)
        {
        case 0: return tr("Id");
        case 1: return tr("Location");
        case 2: return tr("Ignore count");
        case 3: return tr("Single shot");
        case 4: return tr("Hit count");
        }
    }
    return QVariant();
}

Qt::ItemFlags QLuaScriptBreakpointModel::flags(const QModelIndex &index) const
{
    if(!index.isValid())
        return 0;
    Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    switch(index.column())
    {
    case 0:
        f |= Qt::ItemIsUserCheckable;
        break;
    case 2:
        f |= Qt::ItemIsEditable;
        break;
    case  3:
        f |= Qt::ItemIsUserCheckable;
        break;
    }
    return f;
}
